﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Information.System.Hostd.Authorization;
using Information.System.Hostd.Extensions;
using Information.System.Interfaces;
using Information.System.Model;
using Information.System.Model.Dto.System;
using Information.System.Model.View;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using SqlSugar;

namespace Information.System.Hostd.Controllers.System
{
    /// <summary>
    /// 字典接口
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class DepartmentController : BaseController
    {
        /// <summary>
        /// 会话管理接口
        /// </summary>
        private readonly TokenManager _tokenManager;
        /// <summary>
        /// 日志管理接口
        /// </summary>
        private readonly ILogger<DepartmentController> _logger;

        /// <summary>
        /// 字典接口
        /// </summary>
        private readonly ISysDepartmentService _sysDepartmentService;

        /// <summary>
        /// 用户部门接口
        /// </summary>
        private readonly ISysUserDepartmentService _sysUserDepartmentService;

        public DepartmentController(TokenManager tokenManager, ISysDepartmentService sysDepartmentService, ILogger<DepartmentController> logger)
        {
            _tokenManager = tokenManager;
            _sysDepartmentService = sysDepartmentService;
            _logger = logger;
        }

        /// <summary>
        /// 查询字典列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Authorization]
        public IActionResult Query(string name)
        {
            List<Sys_Department> departments = new List<Sys_Department>();
            if (string.IsNullOrEmpty(name))
            {
                //获取系统所有菜单
                departments = _sysDepartmentService.GetAll();

                return toResponse(ResolveTreeNodeVMSelect(departments));
            }

            //开始拼装查询条件
            var predicate = Expressionable.Create<Sys_Department>();

            predicate = predicate.And(m => m.Name.Contains(name)).Or(m => m.Name.Contains(name));

            //获取系统所有字典
            var serachDictionary = _sysDepartmentService.GetWhere(predicate.ToExpression(), m => m.SortIndex);

            return toResponse(ResolveTreeNodeVMSelect(serachDictionary, "-1"));
        }

        /// <summary>
        /// 查询字典
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        [Authorization]
        public IActionResult Get(string id)
        {
            var response = _sysDepartmentService.GetId(id);

            return toResponse(response);
        }

        /// <summary>
        /// 添加部门
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Authorization(Power = "PRIV_DEPARTMENT_CREATE")]
        public IActionResult Create([FromBody] DepartmentDto parm)
        {
            //从 Dto 映射到 实体
            var menu = parm.Adapt<Sys_Department>();

            //如果 ParentID 是 -1 更新为 null
            menu.ParentID = menu.ParentID == "-1" ? null : menu.ParentID;
            if (!string.IsNullOrWhiteSpace(menu.ParentID))
            {
                var parent = _sysDepartmentService.GetId(menu.ParentID);
                menu.Path = parent.Path + "-" + menu.Name;
            }
            else {
                menu.Path = menu.Name;
            }
           
            menu.ToCreate(_tokenManager.GetSessionInfo());
            if (!string.IsNullOrWhiteSpace(menu.ParentID))
            {
                var parent = _sysDepartmentService.GetId(menu.ParentID);
                menu.PathID = parent.PathID + "-" + menu.ID;
            }
            else
            {
                menu.PathID = menu.ID;
            }

            return toResponse(_sysDepartmentService.Add(menu));
        }

        /// <summary>
        /// 更新部门
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Authorization(Power = "PRIV_DEPARTMENT_UPDATE")]
        public IActionResult Update([FromBody] DepartmentDto parm)
        {
            var userSession = _tokenManager.GetSessionInfo();


            parm.ParentID = parm.ParentID == "" ? "0" : parm.ParentID;
            if (!string.IsNullOrWhiteSpace(parm.ParentID) && "0" != parm.ParentID)
            {
                var parent = _sysDepartmentService.GetId(parm.ParentID);
                parm.Path = parent.Path + "-" + parm.Name;
                parm.PathID = parent.PathID + "-" + parm.ID;
            }
            else
            {
                parm.Path = parm.Name;
                parm.PathID = parm.ID;
            }
           
            return toResponse(_sysDepartmentService.Update(m => m.ID == parm.ID, m => new Sys_Department()
            {
                Name = parm.Name,
                ParentID = parm.ParentID,
                SortIndex = parm.SortIndex,
                Remark = parm.Remark,
                Path = parm.Path,
                PathID = parm.PathID,
                UpdateID = userSession.UserID,
                UpdateName = userSession.UserName,
                UpdateTime = DateTime.Now
            }));
        }
        /// <summary>
        /// 删除部门
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Authorization(Power = "PRIV_DEPARTMENT_DELETE")]
        public IActionResult Delete(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return toResponse(StatusCodeType.Error, "删除 Id 不能为空");
            }

            bool hasChildren = _sysDepartmentService.Any(m => m.ParentID == id);

            if (hasChildren)
            {
                return toResponse(StatusCodeType.Error, "检测到下级含有子集，请先删除子集！");
            }

            try
            {
                _sysUserDepartmentService.BeginTran();
                _sysUserDepartmentService.Delete(t => t.DepartmentID == id);
                var response = _sysDepartmentService.Delete(id);
                _sysUserDepartmentService.CommitTran();
                return toResponse(response);
            }
            catch(Exception ex) {
                _sysUserDepartmentService.RollbackTran();
                throw ex;
            }
           

            
        }

        private static List<TreeDepartmentNodeVM> ResolveTreeNodeVMSelect(List<Sys_Department> departments, string parentId = "0")
        {
            List<TreeDepartmentNodeVM> resultMenus = new List<TreeDepartmentNodeVM>();

            List<Sys_Department> datalist = departments;
            if (parentId != "-1")
            {
                datalist = departments.Where(m => m.ParentID == parentId).OrderBy(m => m.SortIndex).ToList();
            }

            foreach (var dicnary in datalist)
            {
                var children = ResolveTreeNodeVMSelect(departments, dicnary.ID);

                TreeDepartmentNodeVM menusVM = new TreeDepartmentNodeVM
                {
                    Id = dicnary.ID,
                    Title = dicnary.Name,
                    Name = dicnary.Name,
                    SortIndex = (int)dicnary.SortIndex,
                    ParentID = dicnary.ParentID,
                    Path = dicnary.Path,
                    Spread = true,
                    LeaderID = dicnary.LeaderID,
                    LeaderName = dicnary.LeaderName,
                    Children = children.Count == 0 ? null : children

                };
                resultMenus.Add(menusVM);
            }

            return resultMenus;
        }
    }
}
